package com.ruoyi.project.payUtils.leshua;


import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.XmlUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.project.payUtils.leshua.model.LsSelectOrderVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class LeshuaPayUtil {

    private static final Logger log = LoggerFactory.getLogger(LeshuaPayUtil.class);

    //支付宝H5
    private final static String ALIPAY_URL = "http://193.112.72.26:88/api/leshua/alipay_h5.aspx";

    //微信小程序
    private final static String WXPAY_XCX_URL = "http://193.112.72.26:88/api/leshua/weixin_xcx.aspx";

    //退款
    private final static String REFUND_URL = "http://193.112.72.26:88/api/wx/tui.aspx";

    //微信公众号
    private final static String REFUND_JSAPI_URL = "http://193.112.72.26:88/api/wx/jsapi.aspx";

    //订单查询
    private final static String SELECT_URL = "http://193.112.72.26:88/api/select.aspx";

    @Value ("${pay.ls.mchId}")
    private String MCHID;

    @Value ("${pay.ls.secret}")
    private String SECRET;

    @Value ("${pay.ls.notifyUrl}")
    private String NOTIFYURL;



    /**
     * @param tradeNo
     * @param fee
     * @param createTime
     * @param userId
     * @param userName
     *
     * @return
     *
     * @throws Exception
     */
    public String alipay (String tradeNo, int fee, Date createTime, Long userId, String userName) throws Exception {
        Map <String, Object> param = new HashMap <>();
        param.put("mch_id", this.MCHID);
        param.put("out_trade_no", tradeNo);
        param.put("body", "找零工");
        param.put("total_fee", fee);
        param.put("notify_url", this.NOTIFYURL);
        param.put("sign", this.getSign(param));
        String xmlbody = HttpRequest.post(ALIPAY_URL).body(XmlUtil.mapToXmlStr(param), "text/xml;charset=UTF-8")
                .execute().body();
        Map <String, Object> xmlMap = XmlUtil.xmlToMap(xmlbody);
        if (xmlMap != null && xmlMap.containsKey("result_code") && "0".equals(xmlMap.get("result_code").toString())) {
            Map <String, String> res = new HashMap();
            res.put("url", xmlMap.get("code_url").toString());
            res.put("trade", tradeNo);

            return JSONObject.toJSONString(res);
        } else {
            log.error("调用支付失败: " + xmlbody);
            return "调用支付失败";
        }
    }

    public Map <String, Object> wxxcxpay (String tradeNo, int fee, Date createTime, Long userId, String userName,
            String opid) throws Exception {
        Map <String, Object> param = new HashMap <>();
        param.put("mch_id", this.MCHID);
        param.put("out_trade_no", tradeNo);
        param.put("body", "找零工");
        param.put("total_fee", fee);
        param.put("notify_url", this.NOTIFYURL);
        param.put("sub_openid", opid);
        param.put("sign", this.getSign(param));
        String xmlbody = HttpRequest.post(WXPAY_XCX_URL).body(XmlUtil.mapToXmlStr(param), "text/xml;charset=UTF-8")
                .execute().body();
        Map <String, Object> xmlMap = XmlUtil.xmlToMap(xmlbody);
        if (xmlMap != null && xmlMap.containsKey("result_code") && "0".equals(xmlMap.get("result_code").toString())) {
            xmlMap.put("trade", tradeNo);
            xmlMap.put("money", fee);

            return xmlMap;
        } else {
            log.error("调用支付失败: " + xmlbody);
            throw new RuntimeException("调用支付失败");
        }
    }

    public Map <String, Object> wxJSPI (String tradeNo, int fee, Date createTime, Long userId, String userName,
            String opid) throws Exception {
        Map <String, Object> param = new HashMap <>();
        param.put("mch_id", this.MCHID);
        param.put("out_trade_no", tradeNo);
        param.put("body", "找零工");
        param.put("total_fee", fee);
        param.put("notify_url", this.NOTIFYURL);
        param.put("sub_openid", opid);
        String sign = this.getSign(param);
        log.info("调用wxJSPI支付签名：{}", sign);
        param.put("sign", sign);
        String xmlbody = HttpRequest.post(REFUND_JSAPI_URL).body(XmlUtil.mapToXmlStr(param), "text/xml;charset=UTF-8")
                .execute().body();
        Map <String, Object> xmlMap = XmlUtil.xmlToMap(xmlbody);
        if (xmlMap != null && xmlMap.containsKey("result_code") && "0".equals(xmlMap.get("result_code").toString())) {
            xmlMap.put("trade", tradeNo);
            xmlMap.put("money", fee);

            return xmlMap;
        } else {
            log.error("调用支付失败: " + xmlbody);
            throw new RuntimeException("调用支付失败");
        }
    }

    /**
     * 退款
     *
     * @param tradeNo
     *         支付订单号
     *
     * @return 按原先接口 失败返回空字符串 成功则有字符串
     */
    public String refund (String tradeNo) {

        Map <String, Object> param = new HashMap <>();
        param.put("mch_id", this.MCHID);
        param.put("transaction_id", tradeNo);
        param.put("timestamp", DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN));
        param.put("sign", this.getSign(param));
        String xmlbody = HttpRequest.post(REFUND_URL).body(XmlUtil.mapToXmlStr(param), "text/xml;charset=UTF-8")
                .execute().body();
        Map <String, Object> xmlMap = XmlUtil.xmlToMap(xmlbody);
        if (xmlMap != null && xmlMap.containsKey("result_code") && "0".equals(xmlMap.get("result_code").toString())) {
            return xmlMap.get("result_code").toString();
        } else {
            log.error("调用支付退款失败: " + xmlbody);
            return "";
        }
    }

    /**
     * 退款
     *
     * @param tradeNo
     *         支付订单号
     *
     * @return 按原先接口 失败返回空字符串 成功则有字符串
     */
    public String eecuteRefund (String transactionId) {
        Map <String, Object> param = new HashMap <>();
        param.put("mch_id", this.MCHID);
        param.put("transaction_id", transactionId);
        param.put("timestamp", DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN));
        param.put("sign", this.getSign(param));
        String xmlbody = HttpRequest.post(REFUND_URL).body(XmlUtil.mapToXmlStr(param), "text/xml;charset=UTF-8")
                .execute().body();
        Map <String, Object> xmlMap = XmlUtil.xmlToMap(xmlbody);
        if (xmlMap != null && xmlMap.containsKey("result_code") && "0".equals(xmlMap.get("result_code").toString())) {
            return xmlMap.get("result_code").toString();
        } else {
            log.error("调用支付退款失败: " + xmlbody);
            return "";
        }
    }

    /**
     * 签名
     *
     * @param param
     *         参数map
     *
     * @return 16进制md5
     */
    private String getSign (Map <String, Object> param) {
        String linkParam = param.keySet().stream().sorted().map(k -> StringUtils.format("{}={}", k, param.get(k)))
                .collect(Collectors.joining("&"));
        log.info("乐刷支付加签参数：{}", linkParam + "&key=" + this.SECRET);
        return DigestUtil.md5Hex(linkParam + "&key=" + this.SECRET).toUpperCase();
    }


    /**
     * executeTradeNoFind 订单查询
     *
     * @param tradeNo
     *         支付订单号
     */
    public Map <String, Object> executeTradeNoFind (String tradeNo) {

        Map <String, Object> param = new HashMap <>();
        param.put("mch_id", this.MCHID);
        param.put("out_trade_no", tradeNo);
        param.put("timestamp", DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN));
        param.put("sign", this.getSign(param));
        String xmlbody = HttpRequest.post(SELECT_URL).body(XmlUtil.mapToXmlStr(param), "text/xml;charset=UTF-8")
                .execute().body();
        Map <String, Object> xmlMap = XmlUtil.xmlToMap(xmlbody);
        if (xmlMap != null && xmlMap.containsKey("result_code") && "0".equals(xmlMap.get("result_code").toString())) {
            return xmlMap;
        } else {
            log.error("调用支付退款失败: " + xmlbody);
            return null;
        }
    }



    /**
     * executeTradeNoFind 订单查询
     *
     * @param tradeNo
     *         支付订单号
     */
    public Map <String, Object> checkTradeNoFind (String tradeNo) {
        Map <String, Object> param = new HashMap <>();
        param.put("mch_id", this.MCHID);
        param.put("out_trade_no", tradeNo);
        param.put("timestamp", DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN));
        param.put("sign", this.getSign(param));
        String xmlbody = HttpRequest.post(SELECT_URL).body(XmlUtil.mapToXmlStr(param), "text/xml;charset=UTF-8")
                .execute().body();

        Map <String, Object> xmlMap = XmlUtil.xmlToMap(xmlbody);
        return xmlMap;

    }


    /**
     * 订单查询
     * @param createPayStartTime 订单创建开始时间
     * @param createPayEndTime  订单创建结束时间
     * @param createRefundStartTime  订单退款开始时间
     * @param createRefundEndTime   订单退款结束时间
     * @return
     */
    public List <LsSelectOrderVo>  selectDayOrder (String createPayStartTime,String createPayEndTime,
            String createRefundStartTime,String createRefundEndTime) {

        Map <String, Object> param = new HashMap <>();
        param.put("mch_id", this.MCHID);
        if(ObjectUtil.isNotEmpty(createPayStartTime) && ObjectUtil.isNotEmpty(createPayEndTime)){
            param.put("k_times", createPayStartTime);
            param.put("j_times", createPayEndTime);
        }
        if(ObjectUtil.isNotEmpty(createRefundStartTime) && ObjectUtil.isNotEmpty(createRefundEndTime)){
            param.put("k_tui_times", createRefundStartTime);
            param.put("j_tui_times", createRefundEndTime);
        }
        param.put("timestamp", DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN));
        param.put("sign", this.getSign(param));
        String xmlbody = HttpRequest.post(SELECT_URL).body(XmlUtil.mapToXmlStr(param), "text/xml;charset=UTF-8")
                .execute().body();
        Map <String, Object> xmlMap = XmlUtil.xmlToMap(xmlbody);
        if (xmlMap != null && xmlMap.containsKey("result_code") && "0".equals(xmlMap.get("result_code").toString())) {
            if(ObjectUtil.isEmpty(xmlMap.get("list"))){
                return null;
            }
            String text = JSONObject.toJSONString(xmlMap.get("list"));
            JSONArray objects = JSON.parseArray(text);
            List <LsSelectOrderVo> monthTaskRes = objects.toJavaList(LsSelectOrderVo.class);
            return monthTaskRes;
        } else {
            log.error("调用支付退款失败: " + xmlbody);
            return null;
        }
    }


    public static void main (String[] args) {
  /*      Map <String, Object> param = new HashMap <>();
        param.put("mch_id", "100152");
        param.put("transaction_id", "0000619633823150");
        param.put("timestamp", DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN));
        String SECRET = "1D15F66DE3BA27166AA036F7742A1F8DCDE38EEAE5AD8DD090";
        String linkParam = param.keySet().stream().sorted().map(k -> StringUtils.format("{}={}", k, param.get(k)))
                .collect(Collectors.joining("&"));
        log.info("乐刷支付加签参数：{}", linkParam + "&key=" + SECRET);
        String sign = DigestUtil.md5Hex(linkParam + "&key=" + SECRET).toUpperCase();
        param.put("sign", sign);
        String xmlbody = HttpRequest.post(REFUND_URL).body(XmlUtil.mapToXmlStr(param), "text/xml;charset=UTF-8")
                .execute().body();
        Map <String, Object> xmlMap = XmlUtil.xmlToMap(xmlbody);
        System.out.println("xmlMap:" + JSONObject.toJSONString(xmlMap));*/

        /*long startTime = System.currentTimeMillis();
        Map <String, Object> param = new HashMap <>();
        param.put("mch_id", "100152");
        param.put("out_trade_no", "111-374364-2186656985795070");
        param.put("body", "找零工");
        param.put("total_fee", "202000");
        param.put("notify_url", "https://zlgadmin.linglinggong.net/nt/pay/lsNotifyUrl");
        param.put("sub_openid", "oucdf5B0WJmvOCdSUIGUJ8hLimZA");

        String SECRET = "1D15F66DE3BA27166AA036F7742A1F8DCDE38EEAE5AD8DD090";
        String linkParam = param.keySet().stream().sorted().map(k -> StringUtils.format("{}={}", k, param.get(k)))
                .collect(Collectors.joining("&"));
        String sign = DigestUtil.md5Hex(linkParam + "&key=" + SECRET).toUpperCase();

        param.put("sign", sign);
        String xmlbody = HttpRequest.post(WXPAY_XCX_URL).body(XmlUtil.mapToXmlStr(param), "text/xml;charset=UTF-8")
                .execute().body();
        Map <String, Object> xmlMap = XmlUtil.xmlToMap(xmlbody);
        System.out.println(JSONObject.toJSONString(xmlMap));
        long endTime = System.currentTimeMillis();
        long totalTime = endTime - startTime;
        System.out.println(totalTime);*/


        Map <String, Object> param = new HashMap <>();
        param.put("mch_id", "100152");
/*        param.put("k_tui_times", "23-11-23 00:00:00");
        param.put("j_tui_times", "23-11-23 23:59:59");*/
     /*   param.put("k_times", "23-11-21 00:00:00");
        param.put("j_times", "23-11-21 23:59:59");*/
        param.put("out_trade_no","ZLG41000002085665143");
        param.put("zt", "1");



        param.put("timestamp", DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN));
        String SECRET = "1D15F66DE3BA27166AA036F7742A1F8DCDE38EEAE5AD8DD090";
        String linkParam = param.keySet().stream().sorted().map(k -> StringUtils.format("{}={}", k, param.get(k)))
                .collect(Collectors.joining("&"));
        String sign = DigestUtil.md5Hex(linkParam + "&key=" + SECRET).toUpperCase();

        param.put("sign", sign);
        String xmlbody = HttpRequest.post(SELECT_URL).body(XmlUtil.mapToXmlStr(param), "text/xml;charset=UTF-8")
                .execute().body();
        System.out.println(xmlbody);
        Map <String, Object> xmlMap = XmlUtil.xmlToMap(xmlbody);
        String text = JSONObject.toJSONString(xmlMap.get("list"));

        JSONArray objects = JSON.parseArray(text);
        List <LsSelectOrderVo> monthTaskRes = objects.toJavaList(LsSelectOrderVo.class);

        System.out.println("xmlMap:"+JSONObject.toJSONString(xmlMap));

    }


}
